﻿using System;
using System.Linq;
using ECommon.Components;
using Infrastructure;
using QueryServices.DTOs;
using System.Collections.Generic;

namespace QueryServices.Ef
{
    [Component]
    public class PostQueryService : BaseQueryService, IPostQueryService
    {
        public PostQueryResult Find(PostQueryOption option)
        {
            int totalCount;
            List<QueryServices.DTOs.PostInfo> posts;

            using (Repository.EntityFramework.Forums.DataContext db = new Repository.EntityFramework.Forums.DataContext())
            {
                var q = db.Post.AsNoTracking().AsQueryable();
                if (!string.IsNullOrEmpty(option.SectionId))
                {
                    q = q.Where(x => x.SectionId == option.SectionId);
                }
                if (!string.IsNullOrEmpty(option.AuthorId))
                {
                    q = q.Where(x => x.AuthorId == option.AuthorId);
                }
                totalCount = q.Count();

                posts = q.OrderByDescending(x=>x.Sequence).Skip(option.PageInfo.Start).Take(option.PageInfo.Limit).Select(x =>
                    new QueryServices.DTOs.PostInfo
                    {
                        AuthorId = x.AuthorId,
                        //AuthorName = "-",
                        Body = x.Body,
                        CreatedOn = x.CreatedOn,
                        Id = x.Id,
                        LastUpdateTime = x.LastUpdateTime,
                        MostRecentReplierId = x.MostRecentReplierId,
                        //MostRecentReplierName = "-",
                        MostRecentReplyId = x.MostRecentReplyId,
                        ReplyCount = x.ReplyCount,
                        //ReplyList = null,
                        SectionId = x.SectionId,
                        Subject = x.Subject,
                        UpdatedOn = x.UpdatedOn
                    }).ToList();
            }

            using (Repository.EntityFramework.Accounts.DataContext db = new Repository.EntityFramework.Accounts.DataContext())
            {
                foreach (var post in posts)
                {
                    post.AuthorName = db.AccountInfo.Where(x => x.Id == post.AuthorId).Select(x => x.Name).SingleOrDefault();
                    post.MostRecentReplierName = db.AccountInfo.Where(x => x.Id == post.MostRecentReplierId).Select(x => x.Name).SingleOrDefault();
                }
            }
            return new PostQueryResult { Posts = posts, TotalCount = totalCount };
        }
        public PostInfo Find(string postId)
        {
            QueryServices.DTOs.PostInfo post;
            List<QueryServices.DTOs.ReplyInfo> replyList;

            using (Repository.EntityFramework.Forums.DataContext db = new Repository.EntityFramework.Forums.DataContext())
            {
                var q = db.Post.AsNoTracking().Where(x => x.Id == postId);
                post = q.Select(x => new QueryServices.DTOs.PostInfo
                    {
                        AuthorId = x.AuthorId,
                        //AuthorName = "-",
                        Body = x.Body,
                        CreatedOn = x.CreatedOn,
                        Id = x.Id,
                        LastUpdateTime = x.LastUpdateTime,
                        MostRecentReplierId = x.MostRecentReplierId,
                        //MostRecentReplierName = "-",
                        MostRecentReplyId = x.MostRecentReplyId,
                        ReplyCount = x.ReplyCount,
                        //ReplyList = null,
                        SectionId = x.SectionId,
                        Subject = x.Subject,
                        UpdatedOn = x.UpdatedOn
                    }).SingleOrDefault();

                replyList = db.Reply.AsNoTracking().Where(x => x.PostId == post.Id).OrderBy(x => x.Sequence).Select(
                    x => new QueryServices.DTOs.ReplyInfo
                    {
                        AuthorId = x.AuthorId,
                        //AuthorName = "-",
                        Body = x.Body,
                        CreatedOn = x.CreatedOn,
                        //Floor = 0,
                        Id = x.Id
                    }).ToList();
            }

            if (post != null)
            {
                if (replyList.Count > 0)
                {
                    using (Repository.EntityFramework.Accounts.DataContext db = new Repository.EntityFramework.Accounts.DataContext())
                    {
                        // post AuthorName
                        post.AuthorName = db.AccountInfo
                                .Where(x => x.Id == post.AuthorId)
                                .Select(x => x.Name).SingleOrDefault();


                        string replyAuthorId;
                        for (var index = 0; index < replyList.Count; index++)
                        {
                            replyList[index].Floor = index + 1;
                            replyAuthorId = replyList[index].AuthorId;
                            replyList[index].AuthorName = db.AccountInfo
                                .Where(x => x.Id == replyAuthorId)
                                .Select(x => x.Name).SingleOrDefault();
                        }
                    }
                    post.ReplyList = replyList;
                    post.ReplyCount = replyList.Count();

                    //var mostRecentReply = replyList.Last();
                    //post.MostRecentReplyId = FormatValue(mostRecentReply.Id);
                    //post.MostRecentReplierId = FormatValue(mostRecentReply.AuthorId);
                    //post.MostRecentReplierName = FormatValue(mostRecentReply.AuthorName);
                    //post.LastUpdateTime = mostRecentReply.CreatedOn;
                }
                return post;
            }
            return null;
        }
        public dynamic FindDynamic(string id, string option)
        {
            if (option == "simple")
            {
                using (Repository.EntityFramework.Forums.DataContext db = new Repository.EntityFramework.Forums.DataContext())
                {
                   var post = db.Post.AsNoTracking().Where(x => x.Id == id).Select(x => new
                    {
                        id = x.Id,
                        subject = x.Subject,
                        body = x.Body,
                        authorId = x.AuthorId
                    }).SingleOrDefault();
                   return post;
                }
            }
            throw new Exception("Invalid find option:" + option);
        }

        private static string FormatValue(object value)
        {
            if (value is DBNull || value == null)
            {
                return string.Empty;
            }
            return value.ToString();
        }
    }
}
